home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ian & Stuart's Australian Mac 1993 September
/
September 93.iso
/
Archives
/
Sound
/
MIDI
/
MIDI Utilities
/
CMU Midi Toolkit
/
Source
/
memstream.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-01-09
|
8KB
|
269 lines
#include "switches.h"
#include "cext.h"
#include "stream.h"
#include "memstream.h"
#define READ_ID 28765
#define WRITE_ID 62658
typedef struct my_data {
StreamProcs procs; /* pointers to generic functions */
ushort ID; /* indicates stream type */
char *buff; /* start of memory buffer */
ulong buffSize; /* size of buffer */
ulong position; /* current r/w position in buffer */
} *SelfPtr;
void memstream_close(SelfPtr);
int memstream_getchar(SelfPtr);
boolean memstream_getline(SelfPtr, char *, ushort);
ulong memstream_getpos(SelfPtr);
void memstream_notImplemented(void);
void memstream_putchar(SelfPtr, int);
void memstream_putstring(SelfPtr, char *);
void memstream_setpos(SelfPtr, ulong);
/****************************************************************************
* memstream_OpenRead
* Inputs:
* char *buff: memory buffer to read from
* ulong buffSize: size of buff
* Returns:
* StreamPtr: newly created memory read stream
* Effect:
* creates a new read stream on the given memory buffer.
* returns NULL if there is no more memory.
****************************************************************************/
public StreamPtr memstream_OpenRead(buff, buffSize)
char *buff;
ulong buffSize;
{
SelfPtr newStream = (SelfPtr) malloc(sizeof(struct my_data));
if (newStream == NULL) return NULL;
newStream->procs.close = memstream_close;
newStream->procs.getchr = memstream_getchar;
newStream->procs.getline = memstream_getline;
newStream->procs.getpos = memstream_getpos;
newStream->procs.putchr = memstream_notImplemented;
newStream->procs.putstring = memstream_notImplemented;
newStream->procs.setpos = memstream_setpos;
newStream->ID = READ_ID;
newStream->buff = buff;
newStream->buffSize = buffSize;
newStream->position = 0;
return (StreamPtr) newStream;
}
/****************************************************************************
* memstream_OpenWrite
* Inputs:
* char *buff: memory buffer to write to
* ulong buffSize: size of buff
* Returns:
* StreamPtr: newly created memory write stream
* Effect:
* creates a new write stream on the given memory buffer.
* returns NULL if there is no more memory.
****************************************************************************/
public StreamPtr memstream_OpenWrite(buff, buffSize)
char *buff;
ulong buffSize;
{
SelfPtr newStream = (SelfPtr) malloc(sizeof(struct my_data));
if (newStream == NULL) return NULL;
newStream->procs.close = memstream_close;
newStream->procs.getchr = (int (*)()) memstream_notImplemented;
newStream->procs.getline = (boolean (*)()) memstream_notImplemented;
newStream->procs.getpos = memstream_getpos;
newStream->procs.putchr = memstream_putchar;
newStream->procs.putstring = memstream_putstring;
newStream->procs.setpos = memstream_setpos;
newStream->ID = WRITE_ID;
newStream->buff = buff;
newStream->buffSize = buffSize;
newStream->position = 0;
return (StreamPtr) newStream;
}
/****************************************************************************
* memstream_close
* Inputs:
* SelfPtr self: a memory stream (read or write)
* Effect:
* frees the stream data structure. writes a terminating character to
* the end of the memory buffer if self is a write stream.
****************************************************************************/
private void memstream_close(self)
SelfPtr self;
{
if (self == NULL) return;
if (self->ID == WRITE_ID) {
/* Assumes: always room for terminator character */
self->buff[self->position++] = '\0';
}
free((char *) self);
}
/****************************************************************************
* memstream_getchar
* Inputs:
* SelfPtr self: a memory read stream
* Returns:
* int: value of character read or -1 (EOF) if at the end of the stream
* Effect:
* reads a character from the stream
****************************************************************************/
private int memstream_getchar(self)
SelfPtr self;
{
if (self->position >= self->buffSize) {
return EOF;
} else {
return (int) self->buff[self->position++];
}
}
/****************************************************************************
* memstream_getline
* Inputs:
* SelfPtr self: a memory read stream
* char * buff: string to read line into
* ushort buffSize: length of buff
* Returns:
* boolean: false if we are at the end of the memory stream
* Effect:
* reads a line of characters from the stream. a line is terminated by
* either a newline character or the end of the stream. if buffSize is less
* than the length of a given line, only buffSize characters are consumed.
* (which could potentially cause the client program to think there are
* line breaks where there aren't; watch out!)
* NOTE: the terminating newline character is NOT part of the string
* returned by getline. (thus, the final line in the memory stream looks like
* any other line regardless of whether the memory buffer ends in a newline.)
****************************************************************************/
private boolean memstream_getline(self, line, lineSize)
SelfPtr self;
char *line;
ushort lineSize;
{
ulong bytesLeft = self->buffSize - self->position;
ulong maxBytesToCopy =
(bytesLeft < (lineSize - 1)) ? bytesLeft : (lineSize - 1);
register char *srcPtr = self->buff + self->position;
register char *maxSrcPtr = srcPtr + maxBytesToCopy;
register char *destPtr = line;
if ((lineSize == 0) || (destPtr == NULL)) return false;
while (srcPtr < maxSrcPtr) {
if ((*destPtr++ = *srcPtr++) == '\n') {
destPtr--; /* don't copy '\n' */
break;
}
}
*destPtr = '\0';
self->position = srcPtr - self->buff;
return ((*line != '\0') || (bytesLeft > 0));
}
/****************************************************************************
* memstream_getpos
* Inputs:
* SelfPtr self: a memory stream (read or write)
* Returns:
* ulong: the stream position (i.e. the number of characters from the start)
****************************************************************************/
private ulong memstream_getpos(self)
SelfPtr self;
{
return self->position;
}
/****************************************************************************
* memstream_notImplemented
* Effect:
* prints an error message and exits. used as a placeholder for functions
* that make no sense for a particular sort of stream (e.g. getchar for
* a write stream).
****************************************************************************/
private void memstream_notImplemented()
{
printf("memstream.c: operation not implemented/n");
exit(-1);
}
/****************************************************************************
* memstream_putchar
* Inputs:
* SelfPtr self: a memory write stream
* int ch: the integer value of the character to write
* Effect:
* writes ch to the stream
****************************************************************************/
private void memstream_putchar(self, ch)
SelfPtr self;
int ch;
{
if (self->position < (self->buffSize - 1))
self->buff[self->position++] = (char) ch;
}
/****************************************************************************
* memstream_putstring
* Inputs:
* SelfPtr self: a memory write stream
* char * s: the string to put
* Effect:
* writes the given string to the stream
****************************************************************************/
private void memstream_putstring(self, s)
SelfPtr self;
char *s;
{
ulong bytesLeft = (self->buffSize - self->position) - 2;
/* save a byte for possible terminator character */
ushort stringSize = strlen(s);
ulong maxBytesToCopy = (bytesLeft < stringSize) ? bytesLeft : stringSize;
register char *srcPtr = s;
register char *maxSrcPtr = s + maxBytesToCopy;
register char *destPtr = self->buff + self->position;
while (srcPtr < maxSrcPtr) {
*destPtr++ = *srcPtr++;
}
self->position = destPtr - self->buff;
}
/****************************************************************************
* memstream_setpos
* Inputs:
* SelfPtr self: a memory stream (read or write)
* ulong newPos: the new position
* Effect:
* sets stream position to newPos
****************************************************************************/
private void memstream_setpos(self, newPos)
SelfPtr self;
ulong newPos;
{
self->position = (newPos <= self->buffSize) ? newPos : self->buffSize;
}